package left42dead;

import java.util.Iterator;
import java.util.List;

/**
 * Zombie class, derives from Character.
 */
public class Zombie extends Character
{
    // Counter of tour that the zombie remains stunned
    private int stunTour;

    /**
     * Constructor of Zombie class.
     * @param healthPoints initial HP
     * @param field Field where he's located
     * @param location The location in the field where he's located
     */
    public Zombie (int healthPoints, Field field, Location location)
    {
        super(healthPoints, field, location);
    }

    /**
     * This is what the zombies does most of the time
     * @param newCharacters A list to add newly born humans to (not used)
     */
    public void run (List<Character> newCharacters)
    {
        // Check is stunned
        if (isStunned()) stunTour--;
        else
        {
            // Search for an human
            Location newLocation = hunt(location);

            if (newLocation == null)
            {
                // No food found - try to move to a free location.
                newLocation = getField().freeAdjacentLocation(location);
                if (newLocation != null)
                {
                    setLocation(newLocation);
                }
            }
            // See if it was possible to move.
            else if (newLocation != null)
            {
                setLocation(newLocation);
            }
        }
    }

    /**
     * Tell the zombie to look for human adjacent to its current location.
     * @param location Where in the field it is located.
     * @return Where human was found, or null if it wasn't.
     */
    public Location hunt (Location location)
    {
        Field field = this.getField();
        List<Location> adjacent = field.adjacentLocations(getLocation());
        Iterator<Location> it = adjacent.iterator();
        while (it.hasNext())
        {
            Location where = it.next();
            Object human = field.getObjectAt(where);
            if (human != null && human instanceof Human)
            {
                Human target = (Human) human;
                attack(target);

                if (target.isDead())
                {
                    // Turn the human into Zombie
                    target.setHasBeenInfected(true);
                    return where;
                }

                return null;
            }
        }
        return null;
    }

    /**
     * The zombie attack another character the character loose 5HP
     * @param c charcter attacked by the zombie
     */
    public void attack (Character c)
    {
        c.reduceHealthPoints(5);
    }

    // Accessors and getters
    public void setStunned ()
    {
        stunTour = 3;
    }

    public int getStun ()
    {
        return stunTour;
    }

    public boolean isStunned ()
    {
        return (stunTour > 0);
    }
}
